﻿#include "ssMsgEngine.h"
#include "../tools/ssTools.h"
//#include <cstdio>

namespace StarSeeker
{

ssMsgEngine::ssMsgEngine()
{
	m_maxMsgCount = 100000;
}

ssMsgEngine::~ssMsgEngine()
{
	ExitThread();
}

bool ssMsgEngine::PostMsg(ssMsg_s &m)
{
	if (m_msgList.Size() > m_maxMsgCount)
	{
		return false;
	}
	SS_MUTEX_LOCK(m_mutex)
		m_msgList.PushBack(m);
	SS_MUTEX_UNLOCK(m_mutex)
	return true;
}

bool ssMsgEngine::PostMsg(u32 msgID, u32 subID, ulint param1, ulint param2, ulint param3)
{
	ssMsg_s msg(msgID, subID, param1, param2, param3);
	return PostMsg(msg);
}

void ssMsgEngine::ThreadMemberFunc()
{
	OnThreadRun();
#ifdef SS_THREAD_FRAME_TIMER
	m_timer.Init(10000,true);
#endif
	while (!IsRequestStop())
	{
#ifdef SS_THREAD_FRAME_TIMER
		m_timer.Update();
#endif
		if (m_msgList.Size()>0)
		{
			SS_MUTEX_LOCK(m_mutex)
			if (m_msgList.Size() > 0)
			{
				m_tempList = m_msgList;
				m_msgList.Empty();
			}
			SS_MUTEX_UNLOCK(m_mutex)

			u32 now = ssTime::GetTimeNow().u32p;
			ssList<ssMsg_s>::Iterator itr = m_tempList.Begin();
			while (itr.IsVaild())
			{
				if (itr.Data()->msgID == SS_THREAD_STOP)
				{
					RequestStop();
					break;
				}
				else if (itr.Data()->msgID == SS_TIMER_ONCE)
				{
					if (now > itr.Data()->subID)
					{
						HandleMessage(*itr);
					}
					else
					{
						SS_MUTEX_LOCK(m_mutex)
							m_msgList.PushBack(*itr);
						SS_MUTEX_UNLOCK(m_mutex)
					}
				}
				else
				{
					HandleMessage(*itr);
				}
				++itr;
			}
			m_tempList.Empty();
		}

		ssThreadBase::Sleep(1);
	}
}

void ssMsgEngine::ExitThread()
{
	while (m_msgList.Size()>0)
	{
		ssThreadBase::Sleep(500);
	}
	ssMsg_s m;
	m.msgID = SS_THREAD_STOP;
	PostMsg(m);
	ssThreadBase::Sleep(500);
	WaitForExit();
}

void ssMsgEngine::SetMaxMsgCount(u32 ct)
{
	m_maxMsgCount = ct;
}

StarSeeker::u64 ssMsgEngine::GetMsgCount()
{
	u32 c1 = (u32)m_msgList.Size();
	u32 c2 = (u32)m_tempList.Size();
	return U32MergeU64(c1, c2);
}

}
